<template>
  <div class="component-toolbar">
    <div class="toolbar-header">
      <h3>组件库</h3> 
    </div>
    
    <div class="toolbar-content">
		<div  class="search-bar">
			<el-select v-model="category" placeholder="请选择组件类型" style="margin-bottom: 0.3125rem;" clearable @change="handleCategoryChange">
			    <el-option
			      v-for="item in activeCategories"
			      :key="item.value"
			      :label="item.cnLabel"
			      :value="item.value"
			    />
			</el-select>
			
			<el-input
			    v-model="keywords"
			    placeholder="请输入组件名称回车查询"
			    :suffix-icon="Search"
				@keydown.enter="handleSearch"
				style="margin-bottom: 0.3125rem;"
			/>
			
			<el-select v-model="pagination.pageSize" placeholder="请选择需要查询的数据量" style="margin-bottom: 0.3125rem;"  @change="handleSizeChange">
			    <el-option label="10条" :value="10" />
				<el-option label="20条" :value="20" />
				<el-option label="30条" :value="30" />
				<el-option label="50条" :value="50" />
				<el-option label="100条" :value="100" />
			</el-select>
		</div>
		
		<div>
			<el-scrollbar style="height: calc(100vh - 290px);">
				<div class="components-grid">
				<div
				    v-for="component in tableData"
				    :key="component.id"
				    class="component-item"
				    draggable="true"
				    :data-type="component.type"
				    @dragstart="onDragStart($event, component)"
				>
				    <div class="component-toolbar-item">
				      <div class="component-thumbnail-box">
				        <img
							class="component-thumbnail"
							:src="`${BASE_API}/visual/component/library/cover/${component.thumbnail}?${new Date().getTime()}`"
							:alt="component.name"
							@error="onError"
				        />
				        <div class="component-name-overlay">{{ component.name }}</div>
				      </div>
				    </div>
				</div>
				</div>
			</el-scrollbar>
		</div>
		<div style="padding-right: 8px;padding-top:5px;display: flex;justify-content: center;align-items: center;border-top: 1px solid var(--art-card-border);">
		  <el-pagination
		    v-model:current-page="pagination.currentPage"
		    v-model:page-size="pagination.pageSize"
		    layout="prev, pager, next"
		    :total="pagination.total"
			:background="true"
			:pager-count="5"
		    @size-change="handleSizeChange"
		    @current-change="handleCurrentChange"
		  />
		</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { type ComponentConfig } from './util/DynamicComponentUtil'
import { DictService } from '@/api/sys/dictApi'
import { ComponentLibraryService } from '@/api/visual/componentLibraryApi'
import type { CollapseActiveName } from 'element-plus'
import { axiosInstance } from '@/utils/http/index'
import placeholderImg from '@/assets/img/state/404.png'
import { Search } from '@element-plus/icons-vue'

const BASE_API = axiosInstance.defaults.baseURL
// 响应式数据
const activeCategories = ref<any[]>([])
const loading = ref(false)
const category=ref<string>('');
const keywords=ref<string>('');
const tableData = ref<any[]>([])
// 分页设置
const pagination = reactive({
  currentPage: 1,
  pageSize: 20,
  total: 0
})

const handleCategoryChange=()=>{
	handleSearch();
}

const handleSizeChange = (newPageSize: number) => {
	pagination.pageSize = newPageSize
	fetchData()
}

const handleCurrentChange = (newCurrentPage: number) => {
	pagination.currentPage = newCurrentPage
	fetchData()
}

const handleSearch=()=>{
	pagination.currentPage = 1
	fetchData();
}

const fetchData = async () => {
	loading.value = true
	try{
		const { list, pageNumber, pageSize, totalRow }= await ComponentLibraryService.pages({
			query:{
				category:category.value,
				name:keywords.value
			},
			pageNumber:pagination.currentPage,
			pageSize:pagination.pageSize,
		})
		tableData.value = list;
		
		Object.assign(pagination, { 
			currentPage: pageNumber,
			pageSize: pageSize, 
			total:totalRow,
		})
	}catch(error){
		console.error(error);
	}finally{
		loading.value = false
	}
}

const onError=(e:any)=>{
	const target = e.target as HTMLImageElement;
	target.src = placeholderImg ;
}


const onDragStart = (event: DragEvent, component: ComponentConfig) => {
  if (event.dataTransfer) {
    event.dataTransfer.effectAllowed = 'copy'
    
    // 确保所有必要的数据都被设置
    const componentId = component.id || ''
    const componentType = component.type || ''
    const componentName = component.name || ''
    
    event.dataTransfer.setData('component-id', componentId)
    event.dataTransfer.setData('component-type', componentType)
    event.dataTransfer.setData('component-name', componentName)
    event.dataTransfer.setData('component-config', JSON.stringify(component))
  }
}

const getSelectOptions=async ()=>{
	const data= await DictService.getSelectOptions('visual-app-comp-type')
	activeCategories.value=data
}

// 组件挂载时初始化
onMounted(() => {
  getSelectOptions()
  handleSearch();
})

</script>

<style lang="scss" scoped>
.component-toolbar {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  //background: #f5f7fa;
  border-radius: 4px;
  .toolbar-header {
    display: flex;
    height: 40px;
    align-items: center;
	border-bottom: 1px solid var(--art-card-border);;
	.tab-btn{
		color: var(--art-gray-700);
		cursor: pointer;
		background-color: rgba(var(--art-gray-200-rgb), 0.8);
		transition: color 0.3s;
		transition: all 0.3s;
		padding: 8px;
	}
	.tab-btn:first-child{
		border-right: 1px solid var(--art-card-border); 
	}
  }
  
  .toolbar-content {
    flex: 1;
    overflow: hidden;
    padding: 0px;
	
	.search-bar{
		padding-top: 5px;
		display: flex;
		flex-direction: column;
		flex-wrap: wrap;
		justify-content: center;
		align-items: center;
		border-bottom: 1px solid var(--art-card-border);;
	}
	
    
    .components-grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 8px;
      padding: 8px 0;
    }
    
    .component-item {
     // background: white;
      border: 1px solid var(--art-card-border);
      // border-radius: 6px;
      //padding: 12px;
      cursor: pointer;
      transition: all 0.2s;
      display: flex;
      flex-direction: column;
      align-items: center;
	  padding: 1px;
	  width: 120px;
	  height: 120px;
      
      &:hover {
        border-color: #409eff;
        box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
        // transform: translateY(-1px);
		border:1px solid #409eff;
      }
      
      .component-icon {
        font-size: 24px;
        color: #409eff;
        margin-bottom: 8px;
      }
      
      .component-info {
        text-align: center;
        margin-bottom: 8px;

        .component-name {
          font-size: 12px;
          font-weight: 500;
          color: #303133;
		      width: 120px;
        }
        
        .component-description {
          font-size: 10px;
          color: #909399;
          line-height: 1.2;
        }
      }
      
      .component-preview {
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 4px;
        overflow: hidden;
		scale: 0.3;
        .preview-component {
		  // transform: scale(0.5);
          transform-origin: center;
          // width: 240px;
          // height: 180px;
          pointer-events: none;
        }
      }
    }
  }
}

.component-detail {
  .detail-section {
    margin-bottom: 20px;
    
    h4 {
      margin: 0 0 12px 0;
      font-size: 14px;
      color: #303133;
      border-bottom: 1px solid #e4e7ed;
      padding-bottom: 8px;
    }
    
    p {
      margin: 4px 0;
      font-size: 13px;
      color: #606266;
    }
  }
  
  .preview-container {
    width: 100%;
    height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fafafa;
    border-radius: 4px;
    border: 1px solid #e4e7ed;
    
    .detail-preview {
      transform: scale(0.9);
      transform-origin: center;
    }
  }
}

// 响应式设计
@media (max-width: 768px) {
  .component-toolbar {
    .toolbar-content {
      .components-grid {
        grid-template-columns: 1fr;
      }
    }
  }
}
 :deep(.el-collapse-item__header) {
	border-bottom:1px solid var(--art-card-border);
	color: var(--art-gray-700);
 }
 
 :deep(.el-collapse-item__content) {
 	padding-bottom: 2px;
 }

  .component-toolbar-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 120px;
    height: 120px;
    cursor: pointer;
    transition: box-shadow 0.2s;
  }
  .component-toolbar-item:hover {
    box-shadow: 0 4px 16px rgba(64,158,255,0.12);
  }
  .component-toolbar-item:hover .component-thumbnail {
    box-shadow: 0 6px 24px rgba(64,158,255,0.18);
  }
  .component-thumbnail-box {
    width: 100%;
    height: 100%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  }
  .component-thumbnail {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
  }
  .component-name-overlay {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    color:#ffffff;
    font-size: 14px;
    font-weight: 500;
    background:#000000c5;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
    text-align: center;
    word-break: break-all;
  }
  .component-toolbar-item:hover .component-name-overlay {
    opacity: 1;
    pointer-events: auto;
  }
</style> 